<?php
/**
* @software         [JiJinCMS]
* @author           [上海集锦信息科技有限公司]
* @website          [http://www.jijinweb.com]
* @email            [sunny@jijinweb.com]
**/
//模型缓存包含
@include '../app/data/cache/modelCache.php';
//栏目缓存包含
@include '../app/data/cache/catCache.php';
use think\facade\Db;
use think\facade\Request;
// 应用公共文件
/** 过滤url提交的字符，一般针对搜索
 * @param $str
 * @return string
 */
function repGet($str) :string{
    $str = htmlspecialchars($str);
    $str = strip_tags($str);
    $str = addslashes($str);
    $farr = ["/^select[\s]+|insert[\s]+|and[\s]+|or[\s]+|create[\s]+|update[\s]+|delete[\s]+|alter[\s]+|count[\s]+|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i"];
    $str = preg_replace($farr,'', $str);
    return trim($str);
}
//检查数据表是否存在
function table_exists($table_name){
    return Db::query("SHOW TABLES LIKE '".config('database.connections.mysql.prefix').$table_name."'");
}
/*/超级变态的加密算法
第一遍将原密码通过md5加密，然后将加密后的32个字符每次截取2次再加密。加密结果再截取2位。一共加16次，截取16次，每次截取2位，组合在一起产生新的32位加密字符，然后再来一篇md5
*/
function md6($str,$salt="jijincmsV5"){
    $str=$str.$salt;
    $result=md5($str);
    $pass="";
    for($i=0;$i<16;$i++){
        $start=$i*2;
        $thisPass=md5(substr($result,$start,2));
        $thisPass=substr($thisPass,$start,2);
        $pass.=$thisPass;
    }
    return md5($pass);
}
/** 
  +----------------------------------------------------------------------------------------- 
 * 删除目录及目录下所有文件或删除指定文件 
  +----------------------------------------------------------------------------------------- 
 * @param str $path   待删除目录路径 
 * @param int $delDir 是否删除目录，1或true删除目录，0或false则只删除文件保留目录（包含子目录） 
  +----------------------------------------------------------------------------------------- 
 * @return bool 返回删除状态 
  +----------------------------------------------------------------------------------------- 
 */  
function delDirAndFile($path, $delDir = FALSE) {  
    if (is_array($path)) {  
        foreach ($path as $subPath)  
            delDirAndFile($subPath, $delDir);  
    }  
    if (is_dir($path)) {  
        $handle = opendir($path);  
        if ($handle) {  
            while (false !== ( $item = readdir($handle) )) {  
                if ($item != "." && $item != "..")  
                    is_dir("$path/$item") ? delDirAndFile("$path/$item", $delDir) : unlink("$path/$item");  
            }  
            closedir($handle);  
            if ($delDir)  
                return rmdir($path);  
        }  
    } else {  
        if (file_exists($path)) {  
            return unlink($path);  
        } else {  
            return FALSE;  
        }  
    }  
    clearstatcache();  
}  
//任意字符串转二维数组
function str2arr($str,$arr1_split,$arr2_split){
    $arr=explode($arr1_split,$str);
    $result=array();
    foreach($arr as $key=>$v){
        $vs=array();
        $vs=explode($arr2_split,$v);
        $result[]=$vs;
    }
    return $result;
}
//根据当前catid 返回子当前catid和所有catid
function getSonCat($pid,$catarr=[],$bigModelid=0){
    if(!$catarr){
        $catarr[]=$pid;
        $bigModelid=$GLOBALS["cat"][$pid]["modelid"];//获取最大一级的modelid
    }
    $where[]=["pid","=",$pid];
    $where[]=["status","=",1];
    $cat=Db::name("cat")->field("catid,modelid")->where($where)->order("sort asc")->select();
    if(count($cat)>0){
        foreach($cat as $v){
            //这里判断当前的栏目modelid和最大一级modelid一至，否则不放入结果中
            if($v["modelid"]==$bigModelid){
                $catarr[]=$v['catid'];
            }
            $catarr=getSonCat($v['catid'],$catarr,$bigModelid);                
        }            
        return $catarr;
    }else{
        return $catarr;
    }
}
//生成随机数函数
function make_random($length=8,$type="all"){
    if($type=="num"){
        $str='0123456789';
    }else{
        $str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    }
    $len=strlen($str)-1;
    $randstr='';
    for($i=0;$i<$length;$i++){
        $num=mt_rand(0,$len);
        $randstr .= $str[$num];
    }
    return $randstr;
}
//生成一个14位的随机数（一般是在第一次添加信息的时候因为没有id，用来关联附件的）
function make_pubid(){
    $pubid=time().rand(1000,9999);
    return $pubid;
}
//获取ip地址
function get_client_ip(){
    $forwarded = request()->header("x-forwarded-for");
    if($forwarded){
        $ip = explode(',',$forwarded)[0];
    }else{
        $ip = request()->ip();
    }
    return $ip;
}
//格式化字节大小
function format_bytes($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}
//返回栏目列表
function caturl($catid){
    return $GLOBALS["cat"][$catid]["classpath"];
}
//返回信息url
function titleurl($r){
    //判断提交的参数是否全法
    if(!isset($r["id"])||!isset($r["catid"])){
        return "javascript:alert('此处调用的titleurl函数缺少[id]或[catid]字段');";
    }
    //查询是否包含titleurl link字段
    if(!array_key_exists("titleurl",$r)||!array_key_exists("link",$r)){
        if($GLOBALS["cat"][$r["catid"]]){
            $info=Db::name("cms_".$GLOBALS["cat"][$r["catid"]]["table_name"])->field("titleurl,link")->find($r['id']);
            if(!$r['titleurl']){
                $r['titleurl']=$info['titleurl'];
            }
            if(!$r['link']){
                $r['link']=$info['link'];
            }   
        }
    }      
    if($r['link']){
        $url=$r['link'];
    }
    elseif($r['titleurl']){
        $url=$r['titleurl'];
    }else{
        $url=$GLOBALS["cat"][$r["catid"]]["classpath"].$r["id"].".html";
    }
    return $url;    
}
//自定义页面url
function pageurl($page_id){
    $page=Db::name("page")->field("page_id,classpath")->find($page_id);
    $url=$page["classpath"];
    return $url;      
}
//返回的是一个不包含首页的栏目结构数组
function nav_arr(){
    $catid=Request::param("catid",0,"intval"); 
    $catarr=array();
    if($GLOBALS['cat'][$catid]){        
        $catarr[]=array(
            "catid"=>$catid,
            "name"=>$GLOBALS['cat'][$catid]["name"],
            "modelid"=>$GLOBALS['cat'][$catid]["modelid"],
        );
        for($i=1;$i<=2;$i++){
            $pid=$GLOBALS['cat'][$catid]["pid"];
            if($pid){
                $catarr[]=array(
                    "catid"=>$pid,
                    "name"=>$GLOBALS['cat'][$pid]["name"],
                    "modelid"=>$GLOBALS['cat'][$pid]["modelid"],
                );
                $catid=$pid;
                $i=1;
            }else{
                break;
            }
        }
    }
    //数组颠倒
    if($catarr){
        $catarr=array_reverse($catarr);
    }
    return $catarr;
}
//list标签调用的函数
function listFun(array $config=array(),array $where=array()){
    $return=[];//本函数返回的数组
    //排序
    $config['_order']=$config['_order']?$config['_order']:"sort asc,is_top desc,is_good desc,newstime desc";
    //如果指定field字段，要强制增加系统必要的字段
    if($config['_field']){
        $config['_field']=$config['_field'].",id,catid,titleurl,title";
    }
    $LabelModel=new app\index\model\LabelModel($config,$where);
    $LabelModel->setCatid();
    
    //设置查询条件
    $LabelModel->setWhere();
    //按field排序
    if($config['_orderRaw']){
        $LabelModel->setOrderRaw();
    }     
    //order排序
    if($config['_order']){
      $LabelModel->setOrder();
    }   
      
    if($config['_group']){
        $LabelModel->setGroup();
    }     
    if($config['_having']){
        $LabelModel->setHaving();
    }  
    if($config['_join']){
        $LabelModel->setJoin();
    }      
    if($config['_field']){
        $LabelModel->setField();
    }
    if($config['_limit']){
        $LabelModel->setLimit();
    }    
    if($config['_page_on']){
        $return['page']=$LabelModel->setPaginate();
    }   
    //查询数据
    $LabelModel->select();
    //标题链接
    $LabelModel->set_titleurl();
    //查询副表
    if($config['_data']){
        $LabelModel->select_data();   
    }     
    //查询栏目主表
    if($config['_cat']){
        $LabelModel->select_cat();   
    }    
    //查询栏目副表
    if($config['_cat_data']){
        $LabelModel->select_cat_data();
    }

    $return['data']=$LabelModel->data;
    return $return;
}
//cat标签调用的函数
function catFun(array $config=array(),array $where=array()){
    $return=[];//本函数返回的数组
    //排序
    $config['_order']=$config['_order']?$config['_order']:"sort asc,catid asc";
    $config['_table']="cat";
    //如果指定field字段，要强制增加系统必要的字段
    if($config['_field']){
        $config['_field']=$config['_field'].",catid,classpath,name";
    }
    //默认只调用status为1的栏目
    $hasStatu=0;
    foreach($where as $whereV){
        if($whereV[0]=="status"){
            $hasStatus=1;
        }
    }
    if(!$hasStatus){
        $where[]=['status','=','1'];
    }      
    $LabelModel=new app\index\model\LabelModel($config,$where);
    //
    $LabelModel->setTable();    
    //设置查询条件
    $LabelModel->setWhere();
    //按field排序
    if($config['_orderRaw']){
        $LabelModel->setOrderRaw();
    }     
    //order排序
    if($config['_order']){
      $LabelModel->setOrder();
    } 
    if($config['_group']){
        $LabelModel->setGroup();
    }     
    if($config['_having']){
        $LabelModel->setHaving();
    }  
    if($config['_join']){
        $LabelModel->setJoin();    
    }
    if($config['_field']){
        $LabelModel->setField();
    }
    if($config['_limit']){
        $LabelModel->setLimit();
    }
    if($config['_page_on']){
        $return['page']=$LabelModel->setPaginate();
    }  
    //查询数据
    $LabelModel->select();
    //查询栏目副表
    if($config['_data']){
        $LabelModel->select_cat_data();
    }
    //栏目链接
    $return['data']=$LabelModel->data->each(function($item,$key){
        $item['caturl']=caturl($item['catid']);
        return $item;
    });
    return $return;
}
//table标签调用的函数
function tableFun(array $config=array(),array $where=array()){
    $return=[];//本函数返回的数组
    $LabelModel=new app\index\model\LabelModel($config,$where);
    //
    $LabelModel->setTable();    
    //设置查询条件
    $LabelModel->setWhere();
    //按field排序
    if($config['_orderRaw']){
        $LabelModel->setOrderRaw();
    }     
    //order排序
    if($config['_order']){
      $LabelModel->setOrder();
    } 
    if($config['_group']){
        $LabelModel->setGroup();
    }     
    if($config['_having']){
        $LabelModel->setHaving();
    }  
    if($config['_join']){
        $LabelModel->setJoin();  
    }
    if($config['_field']){
        $LabelModel->setField();
    }
    if($config['_limit']){
        $LabelModel->setLimit();
    }
    if($config['_page_on']){
        $return['page']=$LabelModel->setPaginate();
    }
    //查询数据
    $LabelModel->select();
    $return['data']=$LabelModel->data;
    return $return;
}
//nav标签函数
function navFun($config=array()){
    $catid=$config['catid']?$config['catid']:Request::param("catid",0,"intval");
    $config["startLevel"]=$config["startLevel"]?$config["startLevel"]:1;
    if(!$catid){return;}
    $catarr=array();
    if($GLOBALS['cat'][$catid]){
        $catarr[]=$catid;
        for($i=1;$i<=2;$i++){
            $pid=$GLOBALS['cat'][$catid]["pid"];
            if($pid){
                $catarr[]=$pid;
                $catid=$pid;
                $i=1;
            }else{
                break;
            }
        }
    }
    //数组颠倒
    if($catarr){
        $catarr=array_reverse($catarr);
    }
    $homeStr=isset($config['homeStr'])?$config['homeStr']:'<i class="fa fa-home"></i>首页';
    $homeUrl=isset($config['homeUrl'])?$config['homeUrl']:'/';
    $className=isset($config['className'])?$config['className']:'nav-style';
    $split=isset($config['split'])?$config['split']:'>';
    $navstr='<a href="'.$homeUrl.'" class="'.$className.'">'.$homeStr.'</a>';
    foreach($catarr as $catid){
        //判断是否大于指定要显示的级别
        if($GLOBALS['cat'][$catid]['level']>=$config["startLevel"]){
            $navstr.=$split.'<a href="'.caturl($catid).'" class="'.$className.'">'.$GLOBALS['cat'][$catid]['name'].'</a>';
        }
    }
    return $navstr;
}
//filter标签调用的函数
function filterFun(array $config=array()){
    //默认字段信息
    $config['split']=$config['split']?str_replace(array("\\r","\\n"),array("\r","\n"),$config['split']):"\r\n";
    $config['checkStyle']=$config['checkStyle']?$config['checkStyle']:"on";
    $config['unCheckStyle']=$config['unCheckStyle']?$config['unCheckStyle']:"";
    $config['unsetName']=$config['unsetName']?$config['unsetName']:"全部";
    $config['type']=$config['type']?$config['type']:"auto";
    //如果指定data
    if($config['option']){
        $defaultvalArr=explode(",",$config['option']);
    }else{
    //未指定data将从数据表里找
        $catid=$config['catid']?$config['catid']:Request::param('catid');
        if(!$catid){return;}
        //获取数据表id
        if(!$config['table_id']){
            $modelid=$GLOBALS["cat"][$catid]['modelid'];
            $config['table_id']=$GLOBALS["model"][$modelid]['table_id'];
        }
        //查询字段信息
        $field=Db::name("table_field")->where([
            "table_id"=>$config['table_id'],
            "field"=>$config['field'],
        ])->field('formtype,defaultval')->find();
        //如果$config['type']为auto需要找到表单类型，如果是checkbox,selects设置为模糊查询（value需要变成[value]）
        if($config['type']=="auto"){
            if($field['formtype']=="checkbox"||$field['formtype']=="selects"){
                $config['type']="like";
            }
        }
        $defaultvalArr=explode($config['split'],$field['defaultval']);
    }
    //
    if($config['unset']=="false"){
        $returnStr="";
    }else{
        $className=!Request::get($config['field'])?$config['checkStyle']:$config['unCheckStyle'];
        $returnStr= '<a href="'.reurl($config['field']).'" class="'.$className.'">'.$config['unsetName'].'</a>';
    }

    foreach($defaultvalArr as $v){
        $option_arr=explode("==",$v);
        $name=$option_arr[0];
        $value=$option_arr[1]?$option_arr[1]:$name;
        if($config['type']=="like"){
            $value="[".$value."]";
        }
        $className=Request::get($config['field'])==$value?$config['checkStyle']:$config['unCheckStyle'];
        $returnStr.= '<a href="'.reurl($config['field'],$value).'" class="'.$className.'">'.$name.'</a>';
    }
    return $returnStr;
}
//filter标签调用的函数
function filter2Fun(array $config=array()){
    //默认字段信息
    $config['checkStyle']=$config['checkStyle']?$config['checkStyle']:"on";
    $config['unCheckStyle']=$config['unCheckStyle']?$config['unCheckStyle']:"";
    $config['unsetName']=$config['unsetName']?$config['unsetName']:"全部";
    $config['order']=$config['order']=="desc"?"desc":"asc";
    //
    $catid=$config['catid']?$config['catid']:Request::param('catid');
    $data=Db::name("cms_".$GLOBALS["cat"][$catid]['table_name'])->group($config['field'])->order($config['field']." ".$config['order'])->column($config['field']);
    //
    if($config['unset']=="false"){
        $returnStr="";
    }else{
        $className=!Request::get($config['field'])?$config['checkStyle']:$config['unCheckStyle'];
        $returnStr= '<a href="'.reurl($config['field']).'" class="'.$className.'">'.$config['unsetName'].'</a>';
    }
    foreach($data as $value){
        if ($value){
            $className=Request::get($config['field'])==$value?$config['checkStyle']:$config['unCheckStyle'];
            $returnStr.= '<a href="'.reurl($config['field'],$value).'" class="'.$className.'">'.$value.'</a>';
        }
    }
    return $returnStr;
}
//order标签调用的函数
function orderFun(array $config=array()){
    //默认字段信息
    $config['checkStyle']=$config['checkStyle']?$config['checkStyle']:"on";
    $config['ascStyle']=$config['ascStyle']?$config['ascStyle']:"onUp";
    $config['descStyle']=$config['descStyle']?$config['descStyle']:"onDown";
    $param=Request::get();
    //如果是空字段，则删除排序条件
    if(!$config['field']){
        if(!$param['order']){
            unset($param['order']);
            $returnStr='<a href="'.reurl('ordertype','',$param).'" class="'.$config['checkStyle'].'">'.$config['name'].'</a>';
        }else{
            unset($param['order']);
            $returnStr='<a href="'.reurl('ordertype','',$param).'" class="'.$config['defaultStyle'].'">'.$config['name'].'</a>';
        }        
        return $returnStr;
    }
    //如果当前url没有包含这个排序字段
    if($param['order']!=$config['field']){
        $param['order']=$config['field'];
        $returnStr='<a href="'.reurl('ordertype','desc',$param).'" class="'.$config['defaultStyle'].'">'.$config['name'].'</a>';
        return $returnStr;
    }
    //当前url包含了这个排序字段
    else{
        if(Request::param("ordertype")=="asc"){        
            $returnStr='<a href="'.reurl('ordertype','desc',$param).'" class=" '.$config['checkStyle'].' '.$config['descStyle'].'">'.$config['ascName'].'</a>';
        }else{
            $returnStr='<a href="'.reurl('ordertype','asc',$param).'" class=" '.$config['checkStyle'].' '.$config['ascStyle'].'">'.$config['descName'].'</a>';
        }
        return $returnStr;
    }
}
//link标签调用的函数
function linkFun(array $config=array(),array $where=array()){
    $return=[];//本函数返回的数组
    $config['_table']="link";
    $config['_order']=isset($config['_order'])?$config['_order']:"sort asc,id asc";
    $where[]=["status","=",1];
    $LabelModel=new app\index\model\LabelModel($config,$where);
    //
    $LabelModel->setTable();    
    //设置查询条件
    $LabelModel->setWhere();
    if($config['_order']){
        $LabelModel->setOrder();
    }
    if($config['_limit']){
        $LabelModel->setLimit();
    }
    if($config['_page_on']){
        $return['page']=$LabelModel->setPaginate();
    }
    //查询数据
    $LabelModel->select();
    $return['data']=$LabelModel->data;
    return $return;
}
//ad标签调用的函数
function adFun(array $config=array(),array $where=array()){
    $return=[];//本函数返回的数组
    $config['_table']="ad";
    $config['_order']=isset($config['_order'])?$config['_order']:"sort asc,id asc";
    $where[]=["status","=",1];
    $LabelModel=new app\index\model\LabelModel($config,$where);
    //   
    $LabelModel->setTable();
    //设置查询条件
    $LabelModel->setWhere();
    if($config['_order']){
        $LabelModel->setOrder();
    }
    if($config['_limit']){
        $LabelModel->setLimit();
    }
    if($config['_page_on']){
        $return['page']=$LabelModel->setPaginate();
    }
    //查询数据
    $LabelModel->select();
    $return['data']=$LabelModel->data;
    return $return;
}
//碎片调用
function fragment($field){
    $data=Db::name("fragment")->where("field",$field)->find();
    if($data['type']=="editor"){
        $result=htmlspecialchars_decode($data['content']);
    }else{
        $result=nl2br($data['content']);
    }
    return $result;
}
//替换url参数（一般用于筛选里）
function reurl($field,$value="",$param=[]){
    if(!$param){
        $param=Request::get();
    }
    if(!$value){
        unset($param[$field]);
    }else{
        $param[$field]=$value;
    }
    $url="?".http_build_query($param);
    return $url;
}

/**
 * 数据导出
 * @param array $title   标题行名称
 * @param array $data   导出数据
 * @param string $fileName 文件名
 * @param string $savePath 保存路径
 * @param $type   是否下载  false--保存   true--下载
 * @return string   返回文件全路径
 * @throws PHPExcel_Exception
 * @throws PHPExcel_Reader_Exception
 */
function exportExcel($title=array(), $data=array(), $fileName='', $savePath='./', $isDown=false){
    include('PHPExcel.php');
    $obj = new PHPExcel();

    //横向单元格标识
    $cellName = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ');

    $obj->getActiveSheet(0)->setTitle('sheet名称');   //设置sheet名称
    $_row = 1;   //设置纵向单元格标识
    if($title){
        $_cnt = count($title);
        $obj->getActiveSheet(0)->mergeCells('A'.$_row.':'.$cellName[$_cnt-1].$_row);   //合并单元格
        $obj->setActiveSheetIndex(0)->setCellValue('A'.$_row, '数据导出：'.date('Y-m-d H:i:s'));  //设置合并后的单元格内容
        $_row++;
        $i = 0;
        foreach($title AS $v){   //设置列标题
            $obj->setActiveSheetIndex(0)->setCellValue($cellName[$i].$_row, $v);
            $i++;
        }
        $_row++;
    }

    //填写数据
    if($data){
        $i = 0;
        foreach($data AS $_v){
            $j = 0;
            foreach($_v AS $_cell){
                $obj->getActiveSheet(0)->setCellValue($cellName[$j] . ($i+$_row), $_cell);
                $j++;
            }
            $i++;
        }
    }

    //文件名处理
    if(!$fileName){
        $fileName = uniqid(time(),true);
    }

    $objWrite = PHPExcel_IOFactory::createWriter($obj, 'Excel2007');

    if($isDown){   //网页下载
        header('pragma:public');
        header("Content-Disposition:attachment;filename=$fileName.xls");
        $objWrite->save('php://output');exit;
    }

    $_fileName = iconv("utf-8", "gb2312", $fileName);   //转码
    $_savePath = $savePath.$_fileName.'.xlsx';
    $objWrite->save($_savePath);

    return $savePath.$fileName.'.xlsx';
}